package com.share.two.a_proxy.a_jdk;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/* 3 代理类：将目标类（切入点）和 切面类（通知） 结合 --> 切面
 * 	Proxy.newProxyInstance
 * 		参数1：loader ，类加载器，动态代理类 运行时创建，任何类都需要类加载器将其加载到内存。
 * 			一般情况：当前类.class.getClassLoader();
 * 					目标类实例.getClass().get...
 * 		参数2：Class[] interfaces 代理类需要实现的所有接口
 * 			方式1：目标类实例.getClass().getInterfaces()  ;注意：只能获得自己接口，不能获得父元素接口
 * 			方式2：new Class[]{UserService.class}   
 * 			例如：jdbc 驱动  --> DriverManager  获得接口 Connection
 * 		参数3：InvocationHandler  处理类，接口，必须进行实现类，一般采用匿名内部
 * 			提供 invoke 方法，代理类的每一个方法执行时，都将调用一次invoke
 * 				参数31：Object proxy ：代理对象
 * 				参数32：Method method : 代理对象当前执行的方法的描述对象（反射）
 * 					执行方法名：method.getName()
 * 					执行方法：method.invoke(对象，实际参数)
 * 				参数33：Object[] args :方法实际参数
 * 
 */
public class MyBeanFactory {
	
	
	public static UserService creatBean(){
		final UserService userService = new UserServiceImpl();
		final MyAspect myAspect = new MyAspect();
		
		UserService proxyService = null;
		proxyService = (UserService)Proxy.newProxyInstance(
				MyBeanFactory.class.getClassLoader(), 
				userService.getClass().getInterfaces(), 
				new InvocationHandler() {
					@Override
					public Object invoke(Object proxy, Method method, Object[] args)
							throws Throwable {

						myAspect.before();
						Object obj = method.invoke(userService, args);//执行目标方法
						myAspect.after();

						return obj;
					}
				});

		return proxyService;

	}
	
//	public static UserService createBean1() {
//		
//		
//		final UserService impl = new UserServiceImpl();
//		final MyAspect myAspect = new MyAspect();
//		
//		
//		UserService proxy;
//		proxy = (UserService)Proxy.newProxyInstance(MyBeanFactory.class.getClassLoader(), 
//				impl.getClass().getInterfaces(), 
//				new InvocationHandler() {
//					
//					@Override
//					public Object invoke(Object proxy, Method method, Object[] args)
//							throws Throwable {
//						
//						myAspect.after();
//						Object obj = method.invoke(impl, args);
//						myAspect.before();
//						
//						return obj;
//					}
//				});
//		
//		
//		
//		return proxy;
//	}

}
